## numpyArray to RMatrix.  Converts an array to an RMatrix, or rather an R array as the data can be of arbitrary dimention.

"""
<name>Array to RMatrix</name>
<description>Converts a Numpy Array signal to an RMatrix signal.  This is useful when using functions that expect RMatrix signals.  A companion function RMatrix to Array does the opposite.</description>
<tags>Data Conversion</tags>
<RFunctions></RFunctions>
<icon></icon>
"""


from OWRpy import *
# import OWGUI
import signals
import redRGUI 


class arrayToRMatrix(OWRpy):
    def __init__(self, parent=None, signalManager=None):
        OWRpy.__init__(self, parent, signalManager, 'arrayToRMatrix')
        
        self.setRvariableNames(["conversionMatrix"])
        
        self.inputs = [('Data', signals.conversion.numpyArray, self.gotData)]
        self.outputs = [('Data', signals.conversion.RArray)]
        
        ### GUI ###
        self.infoArea = redRGUI.textEdit(self.controlArea)
        self.infoArea.setHtml('Data not yet processed')
    def gotData(self, data):
        if data:
            ### start the conversion ###
            shape = data.shape
            print shape
            self.R(self.Rvariables['conversionMatrix']+'<-array(dim = c('+','.join([str(b) for b in shape])+'))')
            
            self.setDataLoop(self.Rvariables['conversionMatrix'], shape, data.getData())
            
            newData = signals.conversion.RArray(data = self.Rvariables['conversionMatrix'])
            self.rSend('Data', newData)
            self.infoArea.clear()
            
            self.infoArea.setHtml('Your data has been processed. It looks like this now:</br></br><pre>'+str(self.R('str('+newData.getData()+')'))+'</pre>')
        else:
            self.infoArea.setHtml('No data to process')
    def setDataLoop(self, rvar, shape, data, oldIndicies = []):
        if len(shape) > 2:
            for i in range(shape[0]):
                self.setDataLoop(rvar, shape[1:], data[i], oldIndicies + [i])
                
        else:
            for i in range(shape[0]):
                for j in range(shape[1]):
                    #print ','.join(oldIndicies+[i]+[j])
                    #print self.rString(data[i,j]), type(self.rString(data[i,j]))
                    self.R(rvar+'['+','.join([str(a+1) for a in oldIndicies+[i]+[j]])+'] <- '+self.rString(data[i,j]))
                    
    def rString(self, data):
        try:
            float(data)
            return str(data)
        except:
            return str('\''+str(data)+'\'')